package com.mini.framework.db.mongodb;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.StringUtils;

import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.Mongo;

@SuppressWarnings("unchecked")
public class MongoDBDao <T> {
	
	private static final String confPath = "/conf.properties";
	
	static final String DEFAULT_HOST = "localhost";
	
	static final int DEFAULT_PORT = 27017;
	
	static final String DEFAULT_DB = "test";
	
	static final String objClassName = "class";
	
	static final String PACK = ".";
	
	static final String MONGO_HOST = "mongo.host";
	
	static final String MONGO_PORT = "mongo.port";
	
	static final String MONGO_DB = "mongo.db";
	
	
	Mongo mongo;
	
	DB db;
	
	
	
	public MongoDBDao(){
		Properties properties = new Properties();
		try{
			properties.load(MongoDBDao.class.getResourceAsStream(confPath));
			String host = properties.getProperty(MONGO_HOST)==null?DEFAULT_HOST:properties.getProperty(MONGO_HOST);
			Integer port = properties.get(MONGO_PORT)==null?DEFAULT_PORT:Integer.valueOf(properties.getProperty(MONGO_PORT));
			String dbName = properties.getProperty(MONGO_DB)==null?DEFAULT_DB:properties.getProperty(MONGO_DB);
			mongo = new Mongo(host,port);
			db = mongo.getDB(dbName);
		}catch(Exception e){
			e.printStackTrace();
		}
		
	}
	
	
	/**
	 * 保存.
	 * 
	 * @param obj
	 */
	public void save(T obj){
		Map<String,Object> proMap = getObjMap(obj);
		DBCollection collections = db.getCollection((String)proMap.get(objClassName));
		BasicDBObject dbObj = conver2DBObject(proMap);
		collections.insert(dbObj);
	}
	
	/**
	 * 更新一条记录.
	 * 
	 * @param obj
	 */
	public void update(T obj){
		Map<String,Object> proMap = getObjMap(obj);
		DBCollection collections = db.getCollection((String)proMap.get(objClassName));
		BasicDBObject dbObj = conver2DBObject(proMap);
		collections.save(dbObj);
	}
	
	/**
	 * 查找所有.
	 * 
	 * @param clazz
	 * @return
	 */
	public List<T> findALl(Class<T> clazz){
		List<T> objList = new ArrayList<T>();
		String entityName = StringUtils.substringAfterLast(clazz.getName(),PACK);
		DBCollection collections = db.getCollection(entityName);
		DBCursor cursor = collections.find();
		while(cursor.hasNext()){
			DBObject dbobj = cursor.next();
			try{
				T obj = clazz.newInstance();
				PropertyUtils.copyProperties(obj, dbobj);
				objList.add(obj);
			}catch(Exception e){
				e.printStackTrace();
			}
		}
		return objList;
	}
	
	/**
	 * 取对象名及相关属性.
	 * 
	 * @param obj
	 * @return
	 */
	private Map<String,Object> getObjMap(T obj){
		Map<String,Object> proMap = new HashMap<String,Object>();
		String entityName = StringUtils.substringAfterLast(obj.getClass().getName(),PACK);
		try{
			proMap = PropertyUtils.describe(obj);
			proMap.put(objClassName, entityName);
		}catch(Exception e){
			e.printStackTrace();
		}
		return proMap;
		
	}
	
	/**
	 * 转换为DBObject对象.
	 * 
	 * @param proMap
	 * @return
	 */
	private BasicDBObject conver2DBObject(Map<String,Object> proMap){
		proMap.remove(objClassName);
		BasicDBObject dbObj = new BasicDBObject();
		Iterator<String> keyIt = proMap.keySet().iterator();
		while(keyIt.hasNext()){
			String key = keyIt.next();
			dbObj.put(key, proMap.get(key));
		}
		return dbObj;
	}
	
	
	
	
	

}
